﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using System.IO;
using System.Net;
using WindowsLive;
using System.Web.UI.DataVisualization.Charting;

namespace goMatic
{
    public partial class DeviceData : System.Web.UI.Page
    {
        internal static bool bReadOnly = true;
        internal static dbEntities oDB;
        List<v_HMDeviceDetails> lDetails = new List<v_HMDeviceDetails>();
        string sRoom;
        string sFunction;

        const string LoginCookie = "webauthtoken";

        // Initialize the WindowsLiveLogin module.
        static WindowsLiveLogin wll = new WindowsLiveLogin(true);

        protected static string AppId = wll.AppId;
        protected string CustomerId;
        protected Customers oCostomer;

        protected void Page_Load(object sender, EventArgs e)
        {
            DateTime dStart = DateTime.Now;
            System.Diagnostics.Debug.WriteLine("Start:" + dStart.ToString());

            if (!Page.IsPostBack)
            {
                oDB = new dbEntities();

                try
                {
                    CustomerId = ViewState["CustomerID"] as string;
                }
                catch { }

                /*if (string.IsNullOrEmpty(sCustomer))
                {
                    sCustomer = Request.QueryString["id"];
                }*/

                //Load CustomerID from Cookie
                if (string.IsNullOrEmpty(CustomerId))
                {
                    HttpRequest req = HttpContext.Current.Request;
                    HttpCookie loginCookie = req.Cookies[LoginCookie];

                    if (loginCookie != null)
                    {
                        string token = loginCookie.Value;

                        if (!string.IsNullOrEmpty(token))
                        {
                            WindowsLiveLogin.User user = wll.ProcessToken(token);

                            if (user != null)
                            {
                                CustomerId = oDB.Customers.First(t => t.liveid == user.Id).customerid;
                                ViewState.Add("CustomerID", CustomerId);
                            }
                        }
                    }
                }

                //Go back to default if no CustomerID found
                if (string.IsNullOrEmpty(CustomerId))
                {
                    Response.Redirect("~/Default.aspx");
                    return;
                }

                String sWrite = Request.QueryString["write"];
                sRoom = Request.QueryString["room"];
                sFunction = Request.QueryString["function"];

                /*if (oDB.Database.Connection.State != System.Data.ConnectionState.Open)
                    oDB.Database.Connection.Open();*/

                //Get Rooms and Functions
                if (!string.IsNullOrEmpty(CustomerId))
                {
                    DropDownList1.DataSource = oDB.Rooms.Where(t => t.CustomerId == CustomerId).ToList();
                    DropDownList1.DataTextField = "Name";
                    DropDownList1.DataValueField = "id";
                    DropDownList1.DataBind();

                    DropDownList2.DataSource = oDB.Functions.Where(t => t.CustomerId == CustomerId).ToList();
                    DropDownList2.DataTextField = "Name";
                    DropDownList2.DataValueField = "id";
                    DropDownList2.DataBind();
                }

                if (!string.IsNullOrEmpty(CustomerId))
                {
                    //tb_CustomerID.Text = sCustomer;
                    //pCustomer.Visible = false;
                    ViewState.Add("CustomerID", CustomerId);
                }
                if (!string.IsNullOrEmpty(sWrite))
                    bReadOnly = false;
                else
                    bReadOnly = true;
                if (!string.IsNullOrEmpty(sRoom))
                {
                    DropDownList1.DataBind();
                    DropDownList1.Text = sRoom;
                }
                if (!string.IsNullOrEmpty(sFunction))
                {
                    DropDownList2.DataBind();
                    DropDownList2.Text = sFunction;
                }

                try
                {
                    oDB = new dbEntities();
                    int i = 1;
                    List<Devices> lDevices = oDB.Devices.Where(t => t.CustomerID == CustomerId).ToList();
                    try
                    {
                        List<int> rm = new List<int>();
                        List<int> fn = new List<int>();
                        
                        //Get filtered Rooms and channels
                        try
                        {
                            if (!string.IsNullOrEmpty(sRoom))
                            {
                                int iRoomID = int.Parse(DropDownList1.SelectedValue);
                                rm = oDB.RoomMapping.Where(t => t.RoomId == iRoomID & t.CustomerId == CustomerId).Select(w => w.ChannelId).ToList();
                            }

                            if (!string.IsNullOrEmpty(sFunction))
                            {
                                int iFuncID = int.Parse(DropDownList2.SelectedValue);
                                fn = oDB.FunctionMapping.Where(t => t.FunctionId == iFuncID & t.CustomerId == CustomerId).Select(w => w.ChannelId).ToList();
                            }

                            rm.AddRange(fn);
                        }
                        catch { }


                        foreach (Channels oChannel in oDB.Channels.Where(t => t.IsVisible & t.IsReadable & t.CustomerId == CustomerId & (t.ChannelType == "SWITCH" | t.ChannelType == "MOTION_DETECTOR" | t.ChannelType == "DIMMER" | t.ChannelType == "BLIND" | t.ChannelType == "SHUTTER_CONTACT" | t.ChannelType == "WEATHER" | t.ChannelType == "ROTARY_HANDLE_SENSOR"))) 
                        {
                            try
                            {
                                if (rm.Count > 0)
                                {
                                    if (!rm.Contains(oChannel.id))
                                        continue;
                                }

                                List<ChannelValues> lcval = new List<ChannelValues>();
                                lcval = (from H in oDB.ChannelValues where H.customerid == CustomerId & H.device == oChannel.Address orderby H.C__updatedAt group H by H.valuekey into G select G.OrderByDescending(q => q.C__updatedAt).FirstOrDefault()).ToList();

                                //Devices oDev = oDB.Devices.Where(t => t.id == oChannel.DeviceID).First();
                                Devices oDev = lDevices.Where(t => t.id == oChannel.DeviceID).First();

                                foreach (ChannelValues oVals in lcval)
                                {
                                    try
                                    {
                                        v_HMDeviceDetails oDet = new v_HMDeviceDetails()
                                        {
                                            Address = oChannel.Address,
                                            C__createdAt = oVals.C__createdAt,
                                            ChannelID = oChannel.id,
                                            ChannelType = oChannel.ChannelType,
                                            CustomerID = CustomerId,
                                            Interface = oDev.Interface,
                                            IsReadable = oChannel.IsReadable,
                                            IsVisible = oChannel.IsVisible,
                                            IsWritable = oChannel.IsWritable,
                                            Name = oChannel.Name,
                                            Type = oDev.Type,
                                            value = oVals.value,
                                            valuekey = oVals.valuekey,
                                            valuetype = oVals.valuetype,
                                            vid = i
                                        };
                                        lDetails.Add(oDet);
                                        i++;
                                    }
                                    catch { }
                                }
                            }
                            catch { }
                        }
                    }
                    catch { }


                    /*
                      List<int> rm = new List<int>();
                      List<int> fn = new List<int>();
                      if (!string.IsNullOrEmpty(sRoom))
                      {
                          int iRoomID = int.Parse(DropDownList1.SelectedValue);
                          rm = oDB.RoomMapping.Where(t => t.RoomId == iRoomID & t.CustomerId == CustomerId).Select(w => w.ChannelId).ToList();
                          //lDetails.Where(t => rm.Contains(t.ChannelID)).ToList();
                      }

                      if (!string.IsNullOrEmpty(sFunction))
                      {
                          int iFuncID = int.Parse(DropDownList2.SelectedValue);
                          fn = oDB.FunctionMapping.Where(t => t.FunctionId == iFuncID & t.CustomerId == CustomerId).Select(w => w.ChannelId).ToList();
                          //lDetails = lDetails.Where(t => fn.Contains(t.ChannelID)).ToList();
                      }

                      if (rm.Count > 0 & fn.Count == 0)
                      {
                          lDetails = oDB.v_HMDeviceDetails.Where(t => t.CustomerID == CustomerId & t.IsVisible & rm.Contains(t.ChannelID)).OrderBy(t => t.Name).ToList(); 
                      }

                      if (rm.Count == 0 & fn.Count > 0)
                      {
                          lDetails = oDB.v_HMDeviceDetails.Where(t => t.CustomerID == CustomerId & t.IsVisible & fn.Contains(t.ChannelID)).OrderBy(t => t.Name).ToList();
                      }

                      if (rm.Count > 0 & fn.Count > 0)
                      {
                          lDetails = oDB.v_HMDeviceDetails.Where(t => t.CustomerID == CustomerId & t.IsVisible & fn.Contains(t.ChannelID) & rm.Contains(t.ChannelID)).OrderBy(t => t.Name).ToList();
                      }

                      if (rm.Count == 0 & fn.Count == 0)
                      {
                          lDetails = oDB.v_HMDeviceDetails.Where(t => t.CustomerID == CustomerId & t.IsVisible).OrderBy(t => t.Name).ToList();
                      }
                      */
                    DateTime dStop = DateTime.Now;
                    System.Diagnostics.Debug.WriteLine("Stop:" + dStop.ToString());
                    System.Diagnostics.Debug.WriteLine("Duration (s):" + (dStop - dStart).TotalSeconds.ToString());

                    ViewState.Add("HMDetails", lDetails);
                    populateData2();

                }
                catch (Exception ex)
                {
                    ex.Message.ToString();
                }

            }
            else
            {
                try
                {
                    lDetails = ViewState["HMDetails"] as List<v_HMDeviceDetails>;
                    CustomerId = ViewState["CustomerID"] as string;
                    oDB = new dbEntities();
                    populateData2();
                }
                catch (Exception ex)
                {
                    ex.Message.ToString();
                }
            }


        }

        protected void populateData2()
        {
            Panel1.Controls.Clear();

            //oDB = new rzander_dbEntities();
            lDetails.Count().ToString();
            foreach (v_HMDeviceDetails oDetail in lDetails.OrderBy(t => t.Name))
            {
                try
                {
                    //SWITCH
                    if (oDetail.ChannelType == "SWITCH")
                    {
                        if (oDetail.valuekey == "STATE" | oDetail.valuekey == null)
                        {
                            SWITCH sw = (SWITCH)Page.LoadControl("Controls/SWITCH.ascx");
                            //sw.ID = oDetail.ChannelID.ToString();
                            sw._Details = oDetail;
                            sw.ReadOnly = bReadOnly;
                            sw.StateChanged += sw_StateChanged;

                            if (Panel1.Controls.Count <= 1)
                                Panel1.Controls.Add(new LiteralControl("<hr />"));
                            Panel1.Controls.Add(sw);
                        }

                    }

                    //SHUTTER_CONTACT
                    if (oDetail.ChannelType == "SHUTTER_CONTACT")
                    {
                        if (oDetail.valuekey == "STATE")
                        {
                            SHUTTER_CONTACT sc = (SHUTTER_CONTACT)Page.LoadControl("Controls/SHUTTER_CONTACT.ascx");
                            sc._Details = oDetail;

                            if (Panel1.Controls.Count <= 1)
                                Panel1.Controls.Add(new LiteralControl("<hr />"));
                            Panel1.Controls.Add(sc);
                        }
                    }

                    //ROTARY_HANDLE_SENSOR
                    if (oDetail.ChannelType == "ROTARY_HANDLE_SENSOR")
                    {
                        if (oDetail.valuekey == "STATE")
                        {
                            ROTARY_HANDLE_SENSOR rh = (ROTARY_HANDLE_SENSOR)Page.LoadControl("Controls/ROTARY_HANDLE_SENSOR.ascx");
                            rh._Details = oDetail;

                            if (Panel1.Controls.Count <= 1)
                                Panel1.Controls.Add(new LiteralControl("<hr />"));
                            Panel1.Controls.Add(rh);
                        }
                    }


                    //MOTION
                    if (oDetail.ChannelType == "MOTION_DETECTOR")
                    {
                        if (oDetail.valuekey == "MOTION" | oDetail.valuekey == null)
                        {
                            MOTION mo = (MOTION)Page.LoadControl("Controls/MOTION.ascx");
                            mo._Details = oDetail;
                            try
                            {
                                string sBright = lDetails.First(t => t.Address == oDetail.Address & t.valuekey == "BRIGHTNESS").value;
                                int iBrightness = int.Parse(sBright);
                                mo._Brightness = iBrightness;
                            }
                            catch (Exception ex)
                            {
                                ex.Message.ToString();
                            }

                            if (Panel1.Controls.Count <= 1)
                                Panel1.Controls.Add(new LiteralControl("<hr />"));
                            Panel1.Controls.Add(mo);
                        }
                    }

                    //DIMMER
                    if (oDetail.ChannelType == "DIMMER")
                    {
                        if (oDetail.valuekey == "LEVEL")
                        {
                            DIMMER di = (DIMMER)Page.LoadControl("Controls/DIMMER.ascx");
                            di._Details = oDetail;
                            di.ReadOnly = bReadOnly;
                            di.LevelChanged += di_LevelChanged;

                            if (Panel1.Controls.Count <= 1)
                                Panel1.Controls.Add(new LiteralControl("<hr />"));
                            Panel1.Controls.Add(di);
                        }
                    }

                    //BLIND
                    if (oDetail.ChannelType == "BLIND")
                    {
                        if (oDetail.valuekey == "LEVEL")
                        {
                            BLIND bl = (BLIND)Page.LoadControl("Controls/BLIND.ascx");
                            bl._Details = oDetail;
                            bl.ReadOnly = bReadOnly;
                            bl.LevelChanged += di_LevelChanged;

                            if (Panel1.Controls.Count <= 1)
                                Panel1.Controls.Add(new LiteralControl("<hr />"));
                            Panel1.Controls.Add(bl);
                        }
                    }

                    //TEMPERATURE
                    if (oDetail.ChannelType == "WEATHER")
                    {
                        if (oDetail.valuekey == "TEMPERATURE" | oDetail.valuekey == null)
                        {
                            TEMPERATURE temp = (TEMPERATURE)Page.LoadControl("Controls/TEMPERATURE.ascx");
                            temp._Details = oDetail;
                            temp._Temperature = double.Parse(oDetail.value, System.Globalization.CultureInfo.InvariantCulture);
                            temp.ReadOnly = bReadOnly;
                            try
                            {
                                string sHum = lDetails.First(t => t.Address == oDetail.Address & t.valuekey == "HUMIDITY").value;
                                if (!string.IsNullOrEmpty(sHum))
                                {
                                    temp._Humidity = int.Parse(sHum);
                                }
                            }
                            catch { }

                            if (oDetail.Type == "HM-CC-TC")
                            {
                                temp.TempChanged += temp_TempChanged;
                                try
                                {
                                    temp._TargetTemp = lDetails.First(t => t.Address == oDetail.Address.Replace(":1", ":2") & t.valuekey == "SETPOINT" & t.ChannelType == "CLIMATECONTROL_REGULATOR");
                                }
                                catch { }
                            }

                            if (Panel1.Controls.Count <= 1)
                                Panel1.Controls.Add(new LiteralControl("<hr />"));
                            Panel1.Controls.Add(temp);
                        }
                    }
                }
                catch (Exception ex)
                {
                    ex.Message.ToString();
                }
            }
        }

        void di_LevelChanged(object sender, EventArgs e)
        {
            //Save state...
            ViewState.Add("HMDetails", lDetails);
        }

        void temp_TempChanged(object sender, EventArgs e)
        {
            //Save state...
            ViewState.Add("HMDetails", lDetails);
        }

        void sw_StateChanged(object sender, EventArgs e)
        {
            //Save state...
            ViewState.Add("HMDetails", lDetails);
        }

        protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
        {
            string sURL = "DeviceData.aspx?";
            if (DropDownList1.Text != "%")
            {
                sURL = sURL + "&room=" + DropDownList1.Text;
            }
            if (DropDownList2.Text != "%")
            {
                sURL = sURL + "&function=" + DropDownList2.Text;
            }
            if (!bReadOnly)
            {
                sURL = sURL + "&write=true";
            }

            Response.Redirect(sURL);
        }
    }
}